/*
 * Decompiled with CFR 0_132.
 */
package forward.Module.Modules.Move;


import java.awt.Color;
import java.util.List;

import forward.api.EventHandler;
import forward.api.EventStep;
import forward.api.Events.World.EventMove;
import forward.api.Events.World.EventPreUpdate;
import forward.api.Value.Mode;
import forward.Client;
import forward.Module.Module;
import forward.Module.ModuleType;
import forward.Util.Math.MathUtil;
import forward.Util.PlayerUtil;
import forward.Util.TimeHelper;
import forward.Util.TimerUtil;
import net.minecraft.block.Block;
import net.minecraft.block.BlockAir;
import net.minecraft.block.BlockLiquid;
import net.minecraft.client.Minecraft;
import net.minecraft.potion.Potion;
import net.minecraft.util.AxisAlignedBB;
import net.minecraft.util.BlockPos;
import net.minecraft.util.MathHelper;
import net.minecraft.util.MovementInput;
import net.minecraft.util.Timer;

public class Speed
        extends Module {
    public static int stage;
    public static int aacCount;
    public static TimeHelper timer2 = new TimeHelper();
    public boolean shouldslow = false;
    double movementSpeed;
    int level = 1;
    double down;
    boolean collided = false;
    boolean lessSlow;
    TimerUtil lastCheck = new TimerUtil();
    double less;
    double stair;
    boolean iscolod;
    boolean isJump;
    int stoptick;
    boolean isstep = false;
    private Mode<Enum> mode = new Mode("Mode", "mode", (Enum[])SpeedMode.values(), (Enum)SpeedMode.HypixelHop);
    private double distance;
    private double lastDist;
    private int tick;
    private List<AxisAlignedBB> collidingList;
    private double speed;
    private TimerUtil timer = new TimerUtil();
    public Speed() {
        super("Speed", new String[]{"zoom"}, ModuleType.Move);
        this.setColor(new Color(99, 248, 91).getRGB());
        this.addValues(this.mode);
    }

    public static int getJumpEffect() {
        if (Minecraft.getMinecraft().thePlayer.isPotionActive(Potion.jump))
            return Minecraft.getMinecraft().thePlayer.getActivePotionEffect(Potion.jump).getAmplifier() + 1;
        else
            return 0;
    }

    @Override
    public void onEnable() {
        boolean player = mc.thePlayer == null;
        this.collided = player ? false : mc.thePlayer.isCollidedHorizontally;
        this.lessSlow = false;
        if (mc.thePlayer != null) {
            this.speed = defaultSpeed();
        }
        this.less = 0.0;
        this.lastDist = 0.0;
        stage = 2;
        Timer.timerSpeed = 1.0f;
    }

    @Override
    public void onDisable() {
        speed = PlayerUtil.getBaseMoveSpeed();
        level = 0;
        Timer.timerSpeed = 1.0f;
        this.tick = 0;
        aacCount = 0;
    }

    @EventHandler
    public void onMotion() {
        double xDist = mc.thePlayer.posX - mc.thePlayer.prevPosX;
        double zDist = mc.thePlayer.posZ - mc.thePlayer.prevPosZ;
        lastDist = Math.sqrt(xDist * xDist + zDist * zDist);
    }

    public void setSpeed(double speed) {
        mc.thePlayer.motionX = - Math.sin(this.getDirection()) * speed;
        mc.thePlayer.motionZ = Math.cos(this.getDirection()) * speed;
    }

    public float getDirection() {
        float yaw = mc.thePlayer.rotationYaw;
        if (mc.thePlayer.moveForward < 0.0f) {
            yaw += 180.0f;
        }
        float forward = 1.0f;
        if (mc.thePlayer.moveForward < 0.0f) {
            forward = -0.5f;
        } else if (mc.thePlayer.moveForward > 0.0f) {
            forward = 0.5f;
        }
        if (mc.thePlayer.moveStrafing > 0.0f) {
            yaw -= 90.0f * forward;
        }
        if (mc.thePlayer.moveStrafing < 0.0f) {
            yaw += 90.0f * forward;
        }
        return yaw *= 0.017453292f;
    }

    private boolean canZoom() {
        if (this.mc.thePlayer.moving() && this.mc.thePlayer.onGround) {
            return true;
        }
        return false;
    }

    @EventHandler
    public void onStep(EventStep e){
        isstep = false;
    }

    @EventHandler
    private void onUpdate(EventPreUpdate e) {
        if (this.mode.getValue() == SpeedMode.SlowHop){
            ++level;
            if(level == 2 && mc.thePlayer.onGround && PlayerUtil.isMoving()) {
                if(checksoulsand()) {
                    mc.thePlayer.jump();
                } else {
                    isJump = true;
                }
            } else
                isJump = false;
        }
        if(mode.getValue()==SpeedMode.Hypixel){
            if(isMoving2()) {
                if(mc.thePlayer.onGround)
                    mc.thePlayer.jump();
                else
                    PlayerUtil.strafe(PlayerUtil.getSpeed() * 1.011F);
            }else{
                mc.thePlayer.motionX = 0D;
                mc.thePlayer.motionZ = 0D;
            }
        }

        if(mode.getValue()==SpeedMode.Bhop) {
            if(PlayerUtil.isMoving()) {

                if(mc.thePlayer.onGround) {
                    mc.thePlayer.jump();

                    //float speed = PlayerUtil.getSpeed2() < 0.56F ? PlayerUtil.getSpeed2() * 1.045F : 0.56F;
                    float speed = 0.281F;
                    if(mc.thePlayer.onGround && mc.thePlayer.isPotionActive(Potion.moveSpeed))
                        speed *= 1F + 0.13F * (1 + mc.thePlayer.getActivePotionEffect(Potion.moveSpeed).getAmplifier());

                    PlayerUtil.strafe(speed);
                    return;
                }else if(mc.thePlayer.motionY < 0.2D)
                    mc.thePlayer.motionY -= 0.02D;

                PlayerUtil.strafe(PlayerUtil.getSpeed() * 1.01889F);
            }else{
                mc.thePlayer.motionX = mc.thePlayer.motionZ = 0D;
            }
        }

        this.setSuffix(this.mode.getValue());

    }

    private boolean checksoulsand() {
        if (issoulsand(0, 0)) {
            return true;
        }
        return false;
    }

    private boolean issoulsand(int X, int Z) {
        if (mc.thePlayer.posY < 0.0) {
        }
        for (int off = 0; off < (int) mc.thePlayer.posY + 2; off += 2) {
            Block block = mc.theWorld.getBlockState(new BlockPos(X,-off, Z)).getBlock();
            if(!block.blockRegistry.equals("soul_sand") || !block.blockRegistry.equals("soul_sand"))
                return false;
        }
        return true;
    }

    private double getHypixelBest(double speed, int T) {
        double base = PlayerUtil.getBaseMoveSpeed();
        boolean slow = false;

        if (T == 1) {
            speed = 0.025;
        } else if (mc.thePlayer.onGround && PlayerUtil.isMoving() && T == 2) {
            speed *= 2.149;
        } else if (T == 3) {
            double str = 0.7095;
            double fe = 1.0E-18;
            double strafe = str * (lastDist - base);
            speed = lastDist - (strafe + fe);
            iscolod = true;
        } else {
            if (T == 2 && mc.thePlayer.fallDistance > 0.0) {
                slow = true;
            }
            level = 1;
            speed = lastDist - lastDist / 159.0;
        }

        speed = Math.max(speed - (slow ? (lastDist * speed) * 0.0149336 : (0.0049336 * lastDist)), base);
        return speed;
    }

    @EventHandler
    private void onMove(EventMove e) {
        if (this.mode.getValue() == SpeedMode.SlowHop) {
            Speed Value = (Speed) Client.instance.modulemanager.getModuleByClass(Speed.class);
            double base = PlayerUtil.getBaseMoveSpeed();
            if (level > 0 && !mc.thePlayer.isInWater()) {
                if (level == 2 && mc.thePlayer.onGround && PlayerUtil.isMoving()) {
                    if(!checksoulsand())
                        e.setY(mc.thePlayer.motionY = 0.4086347666785435 + (PlayerUtil.getJumpEffect() * 0.1f));

                } else if (mc.thePlayer.fallDistance < 0.42f) {
                    if (Value.stoptick > 0) {
                        level = 0;
                        speed = PlayerUtil.getBaseMoveSpeed();
                    }
                    if (level > 3) {
                        if (mc.thePlayer.isCollidedVertically) {
                            level = 0;
                            lastDist = 0.0f;
                        }
                    }
                }
                speed = getHypixelBest(speed, level) - 0.0002133;
            } else {
                level = 0;
            }
            if (PlayerUtil.isMoving()) {
                PlayerUtil.setMotion(e, speed);
            } else {
                level = 0;
            }
        }
        else if (this.mode.getValue() == SpeedMode.HypixelHop) {
            if (this.canZoom() && this.stage == 1) {
                this.movementSpeed = 1.66 * MathUtil.getBaseMovementSpeed() - 0.01;
                this.mc.timer.timerSpeed = 1.0f;
            } else if (this.canZoom() && this.stage == 2) {
                this.mc.thePlayer.motionY = 0.408479654374563124241;
                e.setY(0.408479654374563124241);
                this.movementSpeed *= 1.3;
                this.mc.timer.timerSpeed = 1.03f;
            } else if (this.stage == 3) {
                double difference = 0.66 * (this.distance - MathUtil.getBaseMovementSpeed());
                this.movementSpeed = this.distance - difference;
                this.mc.timer.timerSpeed = 1.03f;
            } else {
                List collidingList = this.mc.theWorld.getCollidingBoundingBoxes(this.mc.thePlayer, this.mc.thePlayer.boundingBox.offset(0.0, this.mc.thePlayer.motionY, 0.0));
                if (collidingList.size() > 0 || this.mc.thePlayer.isCollidedVertically && this.stage > 0) {
                    this.stage = this.mc.thePlayer.moving() ? 1 : 0;
                }
                this.movementSpeed = this.distance - this.distance / 189.0;
            }
            this.movementSpeed = Math.max(this.movementSpeed, MathUtil.getBaseMovementSpeed());
            this.mc.thePlayer.setMoveSpeed(e, this.movementSpeed);
            if (this.mc.thePlayer.moving()) {
                ++this.stage;
            }
        }
        if(mode.getValue()==SpeedMode.HypixelSlow) {
            if (mc.thePlayer.isCollidedHorizontally) {
                this.collided = true;
            }
            if (this.collided) {
                Timer.timerSpeed = 1.0f;
                this.stage = -1;
            }
            if (this.stair > 0.0) {
                this.stair -= 0.25;
            }
            this.less -= this.less > 1.0 ? 0.12 : 0.11;
            if (this.less < 0.0) {
                this.less = 0.0;
            }
            if (!this.isInLiquid() && isOnGround(0.01) && isMoving2()) {
                this.collided = mc.thePlayer.isCollidedHorizontally;
                if (this.stage >= 0 || this.collided) {
                    this.stage = 0;
                    double motY = 0.40854674416343167451326 + (double) getJumpEffect() * 0.1;
                    if (this.stair == 0.0) {
                        mc.thePlayer.motionY = motY;
                        EventMove.setY(mc.thePlayer.motionY);
                    }


                }
            }
            this.movementSpeed = this.getHypixelSpeed(this.stage) + 0.0331;
            this.movementSpeed *= 0.901;
            if (this.stair > 0.0) {
                this.movementSpeed *= 0.7 - (double) this.getSpeedEffect() * 0.1;
            }
            if (this.stage < 0) {
                this.movementSpeed = this.defaultSpeed();
            }
            if (this.lessSlow) {
                this.movementSpeed *= 0.92;
            }
            if (this.lessSlow) {
                this.movementSpeed *= 0.92;
            }
            if (this.isInLiquid()) {
                this.movementSpeed = 0.12;
            }
            if (mc.thePlayer.moveForward != 0.0f || mc.thePlayer.moveStrafing != 0.0f) {

                this.setMotion(e, this.movementSpeed);
                ++this.stage;
            }
        }

    }

    private boolean isInLiquid() {
        if (mc.thePlayer == null) {
            return false;
        }
        int x2 = MathHelper.floor_double(mc.thePlayer.boundingBox.minX);
        while (x2 < MathHelper.floor_double(mc.thePlayer.boundingBox.maxX) + 1) {
            int z2 = MathHelper.floor_double(mc.thePlayer.boundingBox.minZ);
            while (z2 < MathHelper.floor_double(mc.thePlayer.boundingBox.maxZ) + 1) {
                BlockPos pos = new BlockPos(x2, (int)mc.thePlayer.boundingBox.minY, z2);
                Block block = mc.theWorld.getBlockState(pos).getBlock();
                if (block != null && !(block instanceof BlockAir)) {
                    return block instanceof BlockLiquid;
                }
                ++z2;
            }
            ++x2;
        }
        return false;
    }

    public boolean isMoving2() {
        Minecraft.getMinecraft();
        if (mc.thePlayer.moveForward == 0.0f) {
            if (mc.thePlayer.moveStrafing == 0.0f) {
                return false;
            }
        }
        return true;
    }

    public boolean isOnGround(double height) {
        if (!this.mc.theWorld.getCollidingBoundingBoxes(mc.thePlayer, mc.thePlayer.getEntityBoundingBox().offset(0.0, - height, 0.0)).isEmpty()) {
            return true;
        }
        return false;
    }

    private double defaultSpeed() {
        double baseSpeed = 0.2873;
        if (mc.thePlayer.isPotionActive(Potion.moveSpeed)) {
            int amplifier = mc.thePlayer.getActivePotionEffect(Potion.moveSpeed).getAmplifier();
            baseSpeed *= 1.0 + 0.2 * (double)(amplifier + 1);
        }
        return baseSpeed;
    }

    private void setMotion(EventMove em2, double speed) {
        double forward = MovementInput.moveForward;
        double strafe = MovementInput.moveStrafe;
        float yaw = mc.thePlayer.rotationYaw;
        if (forward == 0.0 && strafe == 0.0) {
            em2.setX(0.0);
            em2.setZ(0.0);
        } else {
            if (forward != 0.0) {
                if (strafe > 0.0) {
                    yaw += (float)(forward > 0.0 ? -45 : 45);
                } else if (strafe < 0.0) {
                    yaw += (float)(forward > 0.0 ? 45 : -45);
                }
                strafe = 0.0;
                if (forward > 0.0) {
                    forward = 1.0;
                } else if (forward < 0.0) {
                    forward = -1.0;
                }
            }
            em2.setX(forward * speed * Math.cos(Math.toRadians(yaw + 90.0f)) + strafe * speed * Math.sin(Math.toRadians(yaw + 90.0f)));
            em2.setZ(forward * speed * Math.sin(Math.toRadians(yaw + 90.0f)) - strafe * speed * Math.cos(Math.toRadians(yaw + 90.0f)));
        }
    }
    public int getSpeedEffect() {
        if (mc.thePlayer.isPotionActive(Potion.moveSpeed)) {
            return mc.thePlayer.getActivePotionEffect(Potion.moveSpeed).getAmplifier() + 1;
        }
        return 0;

    }


    private double getHypixelSpeed(int stage) {
        double value = defaultSpeed() + 0.028 * (double)getSpeedEffect() + (double)getSpeedEffect() / 15.0;
        double firstvalue = 0.4145 + (double)getSpeedEffect() / 12.5;
        double decr = (double)stage / 500.0 * 2.0;
        if (stage == 0) {
            if (this.timer.delay(300.0f)) {
                this.timer.reset();
            }
            if (!this.lastCheck.delay(500.0f)) {
                if (!this.shouldslow) {
                    this.shouldslow = true;
                }
            } else if (this.shouldslow) {
                this.shouldslow = false;
            }
            value = 0.64 + ((double)getSpeedEffect() + 0.028 * (double)getSpeedEffect()) * 0.134;
        } else if (stage == 1) {
            value = firstvalue;
        } else if (stage >= 2) {
            value = firstvalue - decr;
        }
        if (this.shouldslow || !this.lastCheck.delay(500.0f) || this.collided) {
            value = 0.2;
            if (stage == 0) {
                value = 0.0;
            }
        }
        return Math.max(value, this.shouldslow ? value : defaultSpeed() + 0.028 * (double)getSpeedEffect());
    }

    static enum SpeedMode {
        HypixelHop,
        SlowHop,
        HypixelSlow,
        Hypixel,
        Bhop;
    }

}

